package com.zhanggod.jcheck.utils.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.zhanggod.jcheck.utils.redis.RedisBase;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author pc
 */
@Slf4j
@Component
public class TokenUtils implements Serializable {

    private static final long serialVersionUID = -3L;

    @Resource
    private RedisBase redisBase;

    /**
     * 令牌存储标识头
     */
    public static String key = "TOKEN_KEY_";

    /**
     * key（按照签名算法的字节长度设置key）
     */
    private final static String SECRET_KEY = "0123456789_0123456789_0123456789";

    /**
     * Token 有效时长(2小时)
     */
    private static Long EXPIRATION = Long.valueOf(1000 * 60 * 60 * 2) ;


    /**
     * 生成 token
     * @param userName
     * @param userPass
     * @return
     */
    public String generateToken(String userName, String userPass){
        String result = "";
        try {
            //过期时间
            Date date = new Date(System.currentTimeMillis() + EXPIRATION);
            //秘钥及加密算法
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
            //设置头部信息
            Map<String,Object> header = new HashMap<>(2);
            header.put("typ","JWT");
            header.put("alg","HS256");
            //携带username，password信息，生成签名
            result = JWT.create()
                    .withHeader(header)
                    .withClaim("userName",userName)
                    .withClaim("userPass",userPass)
                    .withExpiresAt(date)
                    .sign(algorithm);
            redisBase.setEx(key + userName, result, EXPIRATION, TimeUnit.MILLISECONDS);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        return result;
    }

    /**
     * @desc   验证token，通过返回 业务实体
     * @create 2022/03/23
     * @params [userPhone]业务需要验证的内容
     * @params [token]需要校验的串
     **/
    public boolean verifyToken(String userPhone, String token){
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            Map<String, Claim> claims = jwt.getClaims();
            Claim uPhone = claims.get("userPhone");
            if (Objects.nonNull(uPhone)) {
                String keyPhone = uPhone.asString();
                if (keyPhone.equals(userPhone)) {
                    return true;
                }
            }
        }catch (Exception e){
            log.error("token 验证失败，异常信息  e={}",e.getMessage());
            e.printStackTrace();
            return false;
        }
        return false;
    }















}
